#ifndef SNAKE_GAMELOGIC_GAMELOGIC_H_
#define SNAKE_GAMELOGIC_GAMELOGIC_H_

#include <Model/Include/Scene.h>

#include <Render/Include/Renderer.h>
#include <Render/Include/IWinWindow.h>

#include <GameLogic/Include/Task.h>
#include <GameLogic/Include/TimeMeter.h>

/// \brief class to resolve all the game logic
class GameLogic
{
public:
    
    /// \brief anum used to indicate user's input
    typedef enum
    {
        RIGHT_ARROW_PRESSED,
        LEFT_ARROW_PRESSED
    }GameInputType;

    /// \brief anum used to indicate user's input
    typedef enum
    {
        RENDER_WITH_DX9,
        RENDER_WITH_DX11
    }GameRenderingPlatform;

    // ========== LIFECYCLE ========== //
    
    /// \brief Constructor
    GameLogic(Render::IWinWindow* window, const GameRenderingPlatform &platform, Render::IWinWindow* auxi_window);
    
    /// \brief Destructor
    virtual ~GameLogic(void);
    
    // ========== OVERLODED OPERATORS ========== //

    // ========== METHODS ========== //
    
    /// \brief loads the game
    void load(const int &scene_size, const int &snake_velocity);

    /// \brief starts running the game
    void run();

    /// \brief indicates user input
    void input(const GameInputType &input_type);

    /// \brief unloads the game
    void unload();
    
    /// \brief switches view from 2D to 3D and viceversa
    void changeView();

    // ========== GETTERS ========== //

    // ========== SETTERS ========== //

    // ========== INQUIRY ========== //

    /// \brief returns if the game has finished
    bool hasTheGameFinished() const;
    
private:
    // ========== INTERNAL METHODS ========== //
    
    /// \brief used to add text to each render pass during game running
    void addGameText();

public:
    /// \brief main task function
    static void main_task_function(void* user_data);
private:
    // ========== ATTRIBUTES ========== //

    /// \brief scene of the game
    Model::Scene* scene;

    /// \brief the snake
    Model::Snake* snake;
    
    /// \brief the renderer
    Render::Renderer* renderer;

    /// \brief the game window
    Render::IWinWindow* window;

    /// \brief 3D view activated
    bool view_in_3D;

    /// \brief stores if the game has finished
    bool game_finished;

    /// \brief object used to meassure time
    TimeMeter* time_meter;
    
    /// \brief main task pointer
    Task* main_task;

    /// \brief points acummulated by the player
    int player_points;
};

#endif // SNAKE_GAMELOGIC_GAMELOGIC_H_
